package com.cloudpivot.receivales.invoice.controller;

import com.alibaba.fastjson.JSONObject;
import com.cloudpivot.receivales.invoice.entity.InvoiceStatusEntity;
import com.cloudpivot.receivales.invoice.pojo.*;
import com.cloudpivot.receivales.invoice.repository.InvoiceRepository;
import com.cloudpivot.receivales.invoice.services.LdtWorkflowServiceResultsImpl;
import com.cloudpivot.receivales.invoice.services.OAWorkflowServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * OA流程开票接口
 */
@Controller
@Slf4j
@RequestMapping("/oaInvoice")
public class InvocieController {

    @Autowired
    private OAWorkflowServiceImpl oaWorkflowService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private LdtWorkflowServiceResultsImpl ldtWorkflowServiceResults;

    @Autowired
    private InvoiceRepository invoiceRepository;
    @Value("${ldt.url}")
    private String url;

    /**
     * 发票开票接口
     */
    @PostMapping("/addInvoice")
    @ResponseBody
    public ResponseResult addInvoice(@Validated @RequestBody KaiPiaoPOJO kaiPiaoPOJO) {
        ResponseResult rsp = new ResponseResult();
        try {
            adjustApplyDetails(kaiPiaoPOJO);
            ResultInfo result = oaWorkflowService.createWorkflow(kaiPiaoPOJO);
            log.info("invoice rsp:{}", result);

            if (isPositiveNumber(result.getRequestid())) {
                rsp.setCode(result.getRequestid());
                rsp.setFlowNumOA(result.getFlowNumOA());
                rsp.setMsg("流程创建正常");
            } else {
                rsp.setCode(result.getFlowNum());
                rsp.setMsg("请求成功，流程发起异常！");
            }
        } catch (Exception e) {
            log.error("开票接口异常", e);
            rsp.setCode("-101");
            rsp.setMsg("接口异常");
        }
        log.info("addInvoice 返回 rsp:{}", rsp);

        return rsp;
    }


    @PostMapping("/invoicestatus")
    @ResponseBody
    public List<InvoiceStatusEntity> processResultPush(@RequestBody List<String> flowIdList) {

        List<InvoiceStatusEntity> list = new ArrayList<>();

        if (flowIdList == null || flowIdList.isEmpty()) {
            return list;
        }
        // 遍历 flowIdList
        for (String flowIdOA : flowIdList) {
            // 如果 flowIdOA 为空，跳过当前循环
            if (flowIdOA == null || flowIdOA.trim().isEmpty()) {
                continue;
            }
            try {
                InvoiceStatusEntity invoiceStatus = invoiceRepository.getInvoiceList(flowIdOA);
                // 判断 invoiceStatus 是否为空
                if (invoiceStatus == null) {
                    //跳过空值
                    continue;
                }
                // 处理返回状态
                if ("到达 6.归档".equals(invoiceStatus.getInvoiceResult())) {
                    invoiceStatus.setInvoiceResult("1");
                } else if ("到达 7.归档（退回）".equals(invoiceStatus.getInvoiceResult())) {
                    invoiceStatus.setInvoiceResult("-1");
                } else {
                    invoiceStatus.setInvoiceResult("0");
                }
                // 添加结果列表
                list.add(invoiceStatus);
            } catch (Exception e) {
                log.info("处理异常------流程id为{}",flowIdOA);
            }
        }
        return list;
    }

    /**
     * 推送开票结果
     */
    @PostMapping("/oaSourceByRequestid")
    @ResponseBody
    public synchronized Map<String, Object> processResultPush(@RequestBody Map<String, Object> map) {
        try {
            OAProcessInformation oaInfo = mapToOAProcessInformation(map);
            String userSrc = Optional.ofNullable(map.get("userSrc")).map(Object::toString).orElse("");
            log.info("流程状态: {}", userSrc);

            if ("reject".equals(userSrc)) {
                return handlePush(map, oaInfo, -1);
            }

            if (StringUtils.isAnyBlank(oaInfo.getFapiaobh(), oaInfo.getTuipiaofph())) {
                return getReturn(1, "无需推送");
            }

            return handlePush(map, oaInfo, 1);
        } catch (Exception e) {
            log.error("处理结果推送异常", e);
            return getReturn(-1, "系统异常");
        }
    }

    /**
     * 发票退票接口
     */
    @PostMapping("/delInvoice")
    @ResponseBody
    public ResponseResult delInvoice(@Validated @RequestBody KaiPiaoPOJO kaiPiaoPOJO) {
        ResponseResult rsp = new ResponseResult();
        try {
            if ("0".equals(kaiPiaoPOJO.getKaipiaolb()) || StringUtils.isBlank(kaiPiaoPOJO.getTuipiaofph())) {
                rsp.setCode("-102");
                rsp.setMsg("退票参数不符合要求");
                return rsp;
            }
            adjustApplyDetails(kaiPiaoPOJO);
            log.info("oaInvoice 请求内容delInvoice:{}", objectMapper.writeValueAsString(kaiPiaoPOJO));
            ResultInfo resultInfo = oaWorkflowService.createWorkflow(kaiPiaoPOJO);
            log.info("invoice rsp:{}", resultInfo.getRequestid());

            if (isPositiveNumber(resultInfo.getRequestid())) {
                rsp.setCode(resultInfo.getRequestid());
                rsp.setFlowNumOA(resultInfo.getFlowNumOA());
                rsp.setMsg("流程创建正常");
            } else {
                rsp.setCode(resultInfo.getFlowNum());
                rsp.setMsg("请求成功，流程发起异常！");
            }
        } catch (Exception e) {
            log.error("退票接口异常", e);
            rsp.setCode("-101");
            rsp.setMsg("接口异常");
        }
        log.info("delInvoice 返回 rsp:{}", rsp);
        return rsp;
    }

    /**
     * 全局异常处理
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ResponseResult> exceptionHandler(MethodArgumentNotValidException e) {
        String msg = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode("-101");
        responseResult.setMsg(msg);
        log.error("参数校验异常: {}", msg);
        return new ResponseEntity<>(responseResult, HttpStatus.BAD_REQUEST);
    }

    /**
     * 调整申请明细，将超过1000条的数据从 iteTow 移动到 iteThree
     */
    private void adjustApplyDetails(KaiPiaoPOJO kaiPiaoPOJO) {
        List<KaiPiaoItemTowPOJO> iteTow = kaiPiaoPOJO.getIteTow();
        List<KaiPiaoItemTowPOJO> iteThree = kaiPiaoPOJO.getIteThree();
        if (iteTow == null || iteTow.size() <= 1000) {
            return;
        }
        if (iteThree == null) {
            iteThree = new ArrayList<>();
            kaiPiaoPOJO.setIteThree(iteThree);
        }
        iteThree.addAll(iteTow.subList(1000, iteTow.size()));
        kaiPiaoPOJO.setIteTow(new ArrayList<>(iteTow.subList(0, 1000)));
    }

    /**
     * 通用处理推送逻辑
     */
    private Map<String, Object> handlePush(Map<String, Object> map, OAProcessInformation oaInfo, int resultCode) {
        String kaipiaolb = Optional.ofNullable(map.get("kaipiaolb")).map(Object::toString).orElse("");
        JSONObject jsonObject = new JSONObject();

        String endpoint;
        if ("7".equals(kaipiaolb) || "3".equals(kaipiaolb)) {
            endpoint = "/invoice/result";
            jsonObject.put("flowIdOA", oaInfo.getRequestid());
            jsonObject.put("invoiceNum", oaInfo.getFapiaobh());
        } else if ("2".equals(kaipiaolb)) {
            endpoint = "/invoice/hongChong/result";
            jsonObject.put("flowIdOA", oaInfo.getRequestid());
            jsonObject.put("invoiceNum", oaInfo.getTuipiaofph());
        } else {
            return getReturn(1, "无需推送");
        }

        jsonObject.put("invoiceResult", resultCode);
        ldtWorkflowServiceResults.pushResult(jsonObject, url + endpoint);
        return getReturn(1, "推送完成");
    }

    /**
     * 将请求 Map 转换为 OAProcessInformation 对象
     */
    private OAProcessInformation mapToOAProcessInformation(Map<String, Object> map) {
        OAProcessInformation oaInfo = new OAProcessInformation();
        oaInfo.setFapiaobh(Optional.ofNullable(map.get("fapiaobh")).map(Object::toString).orElse(""));
        oaInfo.setRequestid(Optional.ofNullable(map.get("requestid")).map(Object::toString).orElse(""));
        oaInfo.setTuipiaofph(Optional.ofNullable(map.get("tuipiaofph")).map(Object::toString).orElse(""));
        return oaInfo;
    }

    /**
     * 校验是否为正整数
     */
    private boolean isPositiveNumber(String value) {
        try {
            return Integer.parseInt(value) > 0;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 返回值封装
     */
    private Map<String, Object> getReturn(int errcode, String errmsg) {
        Map<String, Object> map = new HashMap<>();
        map.put("errcode", errcode);
        map.put("errmsg", errmsg);
        return map;
    }
}